import java.io.*;
import java.lang.management.CompilationMXBean;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Author: 李明达
 * @Date: 2021/3/22 21:27
 */
public class Homework {
    volatile boolean m = true;
    char[] romanNumAns = new char[15];
    int romanNumIndex = 0;

    public void countChar(String str) {
/**从头遍历str中的每一个字符，判断各种情况，注意异常处理。**/

        int countNum = 0;
        int countChar = 0;
        int countSpace = 0;
        int countOthers = 0;
        int flag = 1;
        char s = 0;

        if (str == null || str.length() == 0) {
            System.out.println("输入为空");
            flag = 0;
        }

        if (flag == 1) {
            for (int i = 0; i < str.length(); i++) {
                s = str.charAt(i);
                if (s >= '0' && s <= '9')
                    countNum++;
                else if ((s >= 'a' && s <= 'z') || (s >= 'A' && s <= 'Z'))
                    countChar++;
                else if (s == ' ')
                    countSpace++;
                else
                    countOthers++;
            }

            System.out.println("数字：" + countNum + "个");
            System.out.println("字母：" + countChar + "个");
            System.out.println("空格：" + countSpace + "个");
            System.out.println("其他：" + countOthers + "个");

        }
    }

    public void regexCountChar(String str) {
        /**在阅读学习了同事的代码后写出如下正则表达式的版本**/

        int length = str.length();

        str = str.toLowerCase();

        str = str.replaceAll("\\d", "");
        System.out.println("数字：" + (length - str.length()) + "个");
        length = str.length();
        str = str.replaceAll("[a-z]", "");
        System.out.println("字母：" + (length - str.length()) + "个");
        length = str.length();
        str = str.replaceAll("\\s", "");
        System.out.println("空格：" + (length - str.length()) + "个");
        length = str.length();
        System.out.println("其他：" + length + "个");
    }

    public void threeCount(int[] nums) {

        int i, j;
        int k = 0;
//        int[][] ans = new int[3][];//二维数组必须指定行数
        List<String> ans = new ArrayList<>(); //改用list存储，要使用arraylist
        int t = 0;
        int target = 0;
        boolean flag = true;

        Arrays.sort(nums);

        for (i = 0; i < nums.length - 2; i++)
            for (j = i + 1; j < nums.length; j++) {
                target = -(nums[i] + nums[j]);//会产生数组越界
                k = binarySearch(nums, i + 1, j - 1, target);
                if (k != 0 && i != j && i != k && j != k) {
                    ans.add("[" + nums[i] + "," + nums[k] + "," + nums[j] + "]");
                    t++;//别忘了自增
                }
            }

        //去除list中重复的元素
        ans = ans.stream().distinct().collect(Collectors.toList());


        System.out.print("[");
        for (i = 0; i < ans.size(); i++) {//获取list的长度
            if (i != 0)
                System.out.print(",");
            System.out.print(ans.get(i));
        }
        System.out.print("]");
    }

    public int binarySearch(int[] nums, int i, int j, int target) {//注意返回的值
        int mid = 0;
        while (i <= j) {//这里要有等于，不然可能找不到临界值
            mid = (i + j) / 2;
            if (nums[mid] > target)
                j = mid - 1;//这里要高的减一，低的加一
            if (nums[mid] < target)
                i = mid + 1;
            if (nums[mid] == target)
                return mid;

        }
        return 0;//这里不能return mid

    }

    public void compareAndSet(String nums, String chars) {

        new Thread(() -> {
            for (char s : nums.toCharArray()) {
                while (!m) ;
                System.out.print(s);
                m = false;

            }
        }, "t1").start();
        new Thread(() -> {
            for (char s : chars.toCharArray()) {
                while (m) ;
                System.out.print(s);
                m = true;
            }

        }, "t2").start();

    }

    public char[] romanNum(int num) {

        int count = 0;
        while (num > 0) {
            int res = num % 10;
            num /= 10;
            romanWrite(res, count++, romanNumAns);
        }

        return romanNumAns;


    }

    public void romanWrite(int res, int count, char[] ans) {
        if (res < 4) {
            if (count == 0) {
                for (int i = 0; i < res; i++) {
                    ans[romanNumIndex++] = 'I';
                }
            }
            if (count == 1) {
                for (int i = 0; i < res; i++) {
                    ans[romanNumIndex++] = 'X';
                }
            }
            if (count == 2) {
                for (int i = 0; i < res; i++) {
                    ans[romanNumIndex++] = 'C';
                }
            }
            if (count == 3) {
                for (int i = 0; i < res; i++) {
                    ans[romanNumIndex++] = 'M';
                }
            }
        }
        if (res == 4) {
            if (count == 0) {
                ans[romanNumIndex++] = 'V';
                ans[romanNumIndex++] = 'I';
            }
            if (count == 1) {
                ans[romanNumIndex++] = 'L';
                ans[romanNumIndex++] = 'X';
            }
            if (count == 2) {
                ans[romanNumIndex++] = 'D';
                ans[romanNumIndex++] = 'C';
            }
        }

        if (res == 5) {
            if (count == 0) {
                ans[romanNumIndex++] = 'V';
            }
            if (count == 1) {
                ans[romanNumIndex++] = 'L';
            }
            if (count == 2) {
                ans[romanNumIndex++] = 'D';
            }
        }
        if (res >= 6 && res <= 8) {
            if (count == 0) {
                for (int i = 0; i < res - 5; i++) {//注意要减5
                    ans[romanNumIndex++] = 'I';
                }
                ans[romanNumIndex++] = 'V';
            }
            if (count == 1) {
                for (int i = 0; i < res - 5; i++) {
                    ans[romanNumIndex++] = 'X';
                }
                ans[romanNumIndex++] = 'L';
            }
            if (count == 2) {
                for (int i = 0; i < res - 5; i++) {
                    ans[romanNumIndex++] = 'C';
                }
                ans[romanNumIndex++] = 'D';
            }
        }
        if (res == 9) {
            if (count == 0) {
                ans[romanNumIndex++] = 'X';
                ans[romanNumIndex++] = 'I';
            }
            if (count == 1) {
                ans[romanNumIndex++] = 'C';
                ans[romanNumIndex++] = 'X';
            }
            if (count == 2) {
                ans[romanNumIndex++] = 'M';
                ans[romanNumIndex++] = 'C';
            }
        }
        if (res == 10) {
            if (count == 0) {
                ans[romanNumIndex++] = 'X';
            }
            if (count == 1) {
                ans[romanNumIndex++] = 'C';
            }
            if (count == 2) {
                ans[romanNumIndex++] = 'M';
            }
        }
    }

    public int antiRomanNum(String num) {

        char[] str = num.toCharArray();
        int ans = 0;

        for (int i = 0; i < str.length; i++) {
            if (i != str.length - 1) {//这行很重要，最后一个元素不能越界
                if (str[i] == 'I' && str[i + 1] == 'V') {
                    ans += 4;
                    i++;
                    continue;//注意要加上continue不然后面的单个数字逻辑会重复计数
                } else if (str[i] == 'I' && str[i + 1] == 'X') {
                    ans += 9;
                    i++;
                    continue;
                } else if (str[i] == 'X' && str[i + 1] == 'L') {
                    ans += 40;
                    i++;
                    continue;
                } else if (str[i] == 'X' && str[i + 1] == 'C') {
                    ans += 90;
                    i++;
                    continue;
                } else if (str[i] == 'C' && str[i + 1] == 'D') {
                    ans += 400;
                    i++;
                    continue;
                } else if (str[i] == 'C' && str[i + 1] == 'M') {
                    ans += 900;
                    i++;
                    continue;
                }
            }
            if (str[i] == 'I') ans += 1;
            if (str[i] == 'V') ans += 5;
            if (str[i] == 'X') ans += 10;
            if (str[i] == 'L') ans += 50;
            if (str[i] == 'C') ans += 100;
            if (str[i] == 'D') ans += 500;
            if (str[i] == 'M') ans += 1000;

        }
        return ans;
    }


    public boolean revStr(String str1, String str2) {
        if (str1.length() != str2.length())
            return false;
        int len = str1.length();
        if (len == 0)
            return true;
        for (int i = 0; i < len; i++) {
            //切分s1,切分点为i，产生两个子串subs11和subs12
            String str11 = str1.substring(0, i + 1);
            String str12 = str1.substring(i + 1);
            //切分s2,切分点为s2.length(),产生两个子串subs21和subs22
            String str21 = str2.substring(0, len - i - 1);
            String str22 = str2.substring(len - i - 1);
            //如果21.equals(12)&&22.equals(11) return True
            if (str11.equals(str22) && str12.equals(str21))
                return true;
        }
        return false;
    }

    public String[] myHashMap(String[] ops, String[] kvs) {
        String[] ans = new String[106];

        String[] store = new String[106];
        Arrays.fill(store, "-1");

        for (int i = 0; i < ops.length; i++) {
            if (ops[i].equals("MyHashMap"))
                ans[i] = "null";
            if (ops[i].equals("put")) {
                store[(kvs[i].toCharArray())[1]] = String.valueOf((kvs[i].toCharArray())[3]);
                ans[i] = "null";
            }
            if (ops[i].equals("get")) {
                ans[i] = store[(kvs[i].toCharArray())[1]];
            }
            if (ops[i].equals("remove")) {
                store[(kvs[i].toCharArray())[1]] = "-1";
                ans[i] = "null";
            }
        }
        return ans;
    }

    public int[] recentCounter(int[] t) {
        int[] ans = new int[109];
        Arrays.fill(ans, 0);

        for (int i = 0; i < t.length; i++) {


            if (i == 0)
                ans[i] = 1;
            else {
                int tmp = 0;
                for (int j = 0; j <= i; j++) {
                    if ((t[j] >= t[i - 1] - 3000) && (t[j] < t[i] - 3000))
                        tmp++;
                }
                ans[i] = ans[i - 1] + 1 - tmp;
            }
        }
        return ans;

    }

    public int reverseBinary(int n) {
        n = n >>> 16 | n << 16;
        //00000000111111110000000011111111
        n = (n & 0x00ff00ff) << 8 | (n & 0xff00ff00) >>> 8;
        //00001111000011110000111100001111
        n = (n & 0x0f0f0f0f) << 4 | (n & 0xf0f0f0f0) >>> 4;
        //00110011001100110011001100110011
        n = (n & 0x33333333) << 2 | (n & 0xcccccccc) >>> 2;
        //01010101010101010101010101010101
        return (n & 0x55555555) << 1 | (n & 0xaaaaaaaa) >>> 1;
    }

    /***
     * leetcode 0330
     * @param matrix
     * @param target
     * @return
     */
    public boolean searchMatrix(int[][] matrix, int target) {
        int low = 0;
        int n = matrix[0].length;
        int high = matrix.length * n - 1;
        while (low <= high) {
            int mid = (low + high) / 2;
            int tmp = matrix[mid / n][mid % n];
            if (tmp < target) {
                low = mid + 1;
            }
            if (tmp < target) {
                high = mid - 1;
            }
            if (tmp == target) {
                return true;
            }
        }
        return false;

    }

    public int[] merge(int[] nums1, int m, int[] nums2, int n) {
        int p1 = m - 1;
        int p2 = n - 1;

        while (p1 >= 0 || p2 >= 0) {
            if (p1 != -1 && p2 != -1) {
                if (nums1[p1] > nums2[p2]) {
                    nums1[p1 + p2 + 1] = nums1[p1];
                    p1--;
                } else {
                    nums1[p1 + p2 + 1] = nums2[p2];
                    p2--;
                }
            }
            if (p1 == -1) {
                nums1[p1 + p2 + 1] = nums2[p2];
                p2--;
            } else if (p2 == -1) {
                nums1[p1 + p2 + 1] = nums1[p1];
                p1--;
            }
        }
        return nums1;
    }

    public int removeDuplicates(int[] nums) {
        int k = 2;
        int j = 0;
        for (int i = 0; i < nums.length; i++) {
            if (i <= 1) {
                nums[j++] = nums[i];
                continue;
            }
            if (nums[i] > nums[j - k])//是j不是i
                nums[j++] = nums[i];
        }
        return j;
    }

    public int[] yuandiDelete(Integer[] nums) {
        int k = 1;
        int j = 0;

        Arrays.sort(nums, Collections.reverseOrder());
        for (int i = 0; i < nums.length; i++) {
            if (j < k || nums[i] != nums[j - k]) {
                nums[j++] = nums[i];
            }
        }
        int[] ans = new int[j];
        while (j > 0) {
            j--;
            ans[j] = nums[j];
        }
        return ans;
    }

    public String bigIntegerSum(String str1, String str2) {
        int len1 = str1.length();
        int len2 = str2.length();
        int sum = 0;
        int[] ans = new int[len1 + len2];
        int i = 0;
        int tmp1;
        int tmp2;
        char[] strArray1 = str1.toCharArray();
        char[] strArray2 = str2.toCharArray();

        while (len1 > 0 || len2 > 0) {
            if (len1 > 0)
                tmp1 = strArray1[len1 - 1] - '0';
            else tmp1 = 0;
            if (len2 > 0)
                tmp2 = strArray2[len2 - 1] - '0';
            else tmp2 = 0;
            sum += tmp1 + tmp2;
            ans[i++] = sum % 10;
            sum /= 10;
            len1--;
            len2--;
        }
        String result = "";
        while (i > 0) {
            result += ans[i - 1];
            i--;
        }
        return result;
    }

    public String replaceAll(String str,String target,String replacement){
        return Pattern.compile(target).matcher(str).replaceAll(replacement);
    }


    static class Athlete implements Callable<String> {
        @Override
        public String call() throws Exception {
            double time = 10 + 10 * Math.random();
            System.out.println("跑了跑了！");
            Thread.sleep((long) time);
            return time + "\0";
        }
    }

    static class Server {
        public static void main(String[] args) {
            try {
                ServerSocket serverSocket = new ServerSocket(12345);
                while (true) {
                    Socket socket = serverSocket.accept();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    System.out.println(reader.readLine());
                    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                    writer.write(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
                    writer.flush();
                    writer.close();
                    reader.close();
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    static class Client {
        public static void main(String[] args) {
            try {
                Socket socket = new Socket("localhost", 12345);
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                writer.write("What day is it today?\n");
                writer.flush();
                BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                System.out.println(reader.readLine());
                writer.close();
                reader.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
